package com.zslc.foreignoption.scheduling;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.zslc.foreignoption.config.TweetParamProperties;
import com.zslc.foreignoption.entity.FollowTopic;
import com.zslc.foreignoption.entity.TweetAuthor;
import com.zslc.foreignoption.service.FollowTopicService;
import com.zslc.foreignoption.service.TweetAuthorService;
import com.zslc.foreignoption.service.TweetInfoService;
import com.zslc.foreignoption.util.ApifyUtil;
import com.zslc.foreignoption.util.HttpUtilTest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 定时同步数据到数据库
 */
@EnableScheduling
@Component
@Slf4j
public class SyncDataTask {
    @Value("${crawler.apify_token}")
    private String token;
    @Value("${crawler.datasetIdUrl}")
    private String datasetIdUrl;
    @Value("${crawler.tweetDataUrl}")
    private String tweetDataUrl;
    @Value("${crawler.push_apify_url}")
    private String pushApifyUrl;
    @Resource
    private TweetParamProperties tweetParamProperties;

    @Resource
    private TweetInfoService tweetInfoService;
    @Resource
    private TweetAuthorService tweetAuthorService;
    @Resource
    private FollowTopicService followTopicService;

    private final String paramFormat_global = "{\n" +
            "  \"maxItems\": %s,\n" +
            "  \"sort\": \"%s\",\n" +
            "  \"startUrls\": [\n" +
            "    \"%s\"\n" +
            "  ]\n" +
            "}\n";


//    @Scheduled(cron = "${crawler.corn.pushData}")
    public void pushAuthorData2Apify() {
        String url = pushApifyUrl + "?token=" + token;
        try {
            List<TweetAuthor> authorList = tweetAuthorService.list();
            if (CollectionUtil.isNotEmpty(authorList)) {
                log.info("【定时新增推特作者的推贴】查询推特作者【{}】个",authorList.size());
                List<String> userNameList = authorList.stream().map(TweetAuthor::getUserName).collect(Collectors.toList());
                String startUrl = tweetParamProperties.getStartUrl();
                String condition = "from:%s within_time:%s";
                for (String userName : userNameList) {
                    String paramFormat  = paramFormat_global;

                    String q = String.format(condition, userName, tweetParamProperties.getWithin_time());
                    String qformat = String.format(startUrl, q);
                    String param = String.format(paramFormat, tweetParamProperties.getMaxItems(),tweetParamProperties.getSort(),qformat);
                    JSONObject jsonObject = JSON.parseObject((HttpUtil.post(url, param)), JSONObject.class);
                    log.info("推送数据到APIFY，返回结果：" + JSONObject.toJSONString(jsonObject));

                    JSONObject data = jsonObject.getJSONObject("data");
                    String defaultDatasetId = data.getString("defaultDatasetId");

                    // 等待30秒钟
                    Thread.sleep(30*1000);
                    List<JSONObject> result = ApifyUtil.getTweetData(tweetDataUrl, token, defaultDatasetId);
                    for (JSONObject tweetDataMap : result) {
                        String dataId = tweetDataMap.getString("id");
                        if (StringUtils.isEmpty(dataId)) {
                            continue;
                        }
                        //关注对象id传值为空
                        String accountId = "";
                        Integer num1 = tweetInfoService.insertTweetData(tweetDataMap, accountId);
                    }

                }
            }
        } catch (Exception e) {
            log.error("推送数据到APIFY出错。");
            log.error(e.getMessage(), e);
        }
    }

//    @Scheduled(cron = "${crawler.corn.pushData}")
    public void pushTopicData2Apify() {

        String url = pushApifyUrl + "?token=" + token;
        try {
            List<FollowTopic> followTopicList = followTopicService.list();
            if (CollectionUtil.isNotEmpty(followTopicList)) {
                log.info("【定时新增topic的推贴】查询推特作者【{}】个",followTopicList.size());
                List<String> topicList = followTopicList.stream().map(FollowTopic::getRetrieval).collect(Collectors.toList());
                String startUrl = tweetParamProperties.getStartUrl();
                String condition = "%s within_time:%s";
                for (String topic : topicList) {
                    topic = URLUtil.encode(topic);
                    String paramFormat  = paramFormat_global;

                    String q = String.format(condition, topic, tweetParamProperties.getWithin_time());
                    String qformat = String.format(startUrl, q);
                    String param = String.format(paramFormat, tweetParamProperties.getMaxItems(),tweetParamProperties.getSort(),qformat);
                    log.info("【定时新增topic的推贴】推送数据到APIFY，组装参数：【{}】" , param);
                    JSONObject jsonObject = JSON.parseObject((HttpUtilTest.doPost(url, param)), JSONObject.class);
//                    JSONObject jsonObject = JSON.parseObject((HttpUtil.post(url, param)), JSONObject.class);
                    log.info("【定时新增topic的推贴】推送数据到APIFY，返回结果：" + JSONObject.toJSONString(jsonObject));
                    JSONObject error = jsonObject.getJSONObject("error");
                    if(error != null){
                        log.error("【定时新增topic的推贴】推送数据到APIFY报错，报错内容【{}】",JSONObject.toJSONString(error));
                        continue;
                    }

                    JSONObject data = jsonObject.getJSONObject("data");
                    String defaultDatasetId = data.getString("defaultDatasetId");
                    // 等待30秒钟
                    Thread.sleep(30*1000);
                    List<JSONObject> result = ApifyUtil.getTweetData(tweetDataUrl, token, defaultDatasetId);
                    for (JSONObject tweetDataMap : result) {
                        String dataId = tweetDataMap.getString("id");
                        if (StringUtils.isEmpty(dataId)) {
                            continue;
                        }
                        //关注对象id传值为空
                        String accountId = "";
                        Integer num1 = tweetInfoService.insertTweetData(tweetDataMap, accountId);
                    }

                }
            }

        } catch (Exception e) {
            log.error("推送数据到APIFY出错。");
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 5min一次
     */
//    @Scheduled(cron = "${crawler.corn.syncData}")
    public void syncTweetTask() {
        log.info("【同步Tweet数据到数据库】任务开始。。。");
        long starttime = System.currentTimeMillis();
        try {
            Integer num = 0;

            JSONObject datasetIdResult = getDefaultDatasetId();
            log.info("查询DefaultDatasetId集合的返回体前100字符:" + StringUtils.substring(JSON.toJSONString(datasetIdResult), 0, 100));
            JSONObject dataMap = datasetIdResult.getJSONObject("data");
            JSONArray items = dataMap.getJSONArray("items");
            Set<String> defaultDatasetIdSet = items.parallelStream().map(item -> ((JSONObject) item).getString("defaultDatasetId")).collect(Collectors.toSet());
            log.info("获取到的defaultDatasetIdSet集合为：{}。", JSONObject.toJSONString(defaultDatasetIdSet));
            for (String defaultDatasetId : defaultDatasetIdSet) {
                List<JSONObject> result = ApifyUtil.getTweetData(tweetDataUrl, token, defaultDatasetId);
                for (JSONObject tweetDataMap : result) {
                    String dataId = tweetDataMap.getString("id");
                    if (StringUtils.isEmpty(dataId)) {
                        continue;
                    }
                    //关注对象id传值为空
                    String accountId = "";
                    Integer num1 = tweetInfoService.insertTweetData(tweetDataMap, accountId);
                    num++;
                }
            }

            log.info("【同步Tweet数据到数据库】任务结束,新数据【{}】条，耗时【{}ms】", num, System.currentTimeMillis() - starttime);
        } catch (Exception e) {
            log.error("【同步Tweet数据到数据库】任务出错。", e);
        }
    }

    private JSONObject getDefaultDatasetId() {
        Map<String, Object> params = new HashMap<>();
        params.put("token", token);
        return JSON.parseObject((HttpUtil.get(datasetIdUrl, params)), JSONObject.class);
    }


}
